﻿using System;
using System.Collections.Generic;
using System.Xml;
using System.Xml.XPath;

namespace Allegro.TaskExecution
{
    ///<summary>
    ///</summary>
    public abstract partial class Task
    {
        ///<summary>
        ///</summary>
        ///<returns></returns>
        public static RunActivity RunActivity()
        {
            return new RunActivity();
        }
        ///<summary>
        ///</summary>
        ///<param name="activity"></param>
        ///<returns></returns>
        public static RunActivity RunActivity(ITaskActivity activity)
        {
            return new RunActivity{Activity = activity,};
        }
    }
    ///<summary>
    ///</summary>
    public class RunActivity : Task
    {
        //public ExecuteInContext<object, IExecutionContext> Executor;
        //public ExecuteInTaskContext<object, IExecutionContext> TaskExecutor;

        /// <summary>
        /// Predicate. If not set or evaluates to true, the task will run, otherwise not
        /// </summary>
        public IExecutionCondition If { get; set; }

        ///<summary>
        ///</summary>
        public RunActivity()
        {

        }
        ///<summary>
        ///</summary>
        ///<param name="activity"></param>
        public RunActivity(ITaskActivity activity)
        {
            Activity = activity;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        protected override void ExecuteTask(IExecutionContext context)
        {
            // Navigate to the task execution context
            IExecutionContext executionContext = GetTaskExecutionContext(this, context);

            // Check the condition
            if (If != null && !If.IsTrue(executionContext))
                return;

            // Check if the execution should be suspended or aborted
            CheckIfSuspendOrAbort(executionContext);

            IAtomicTaskActivity activity = Activity as IAtomicTaskActivity;
            if (activity != null)
            {
                if (activity.CanExecute(executionContext))
                {
                    activity.Execute(this, executionContext);
                }
                else
                {
                    // todo: Must handle this
                }
            }
            else
            {
                string msg = string.Format("Illegal context argument when executing BasicTask {0}", Name);
                Log.Error(msg, this, LogEventTypes.TaskEvent);
                throw new ArgumentException(msg);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="persistenceContext"></param>
        protected override void SaveContent(System.Xml.XmlWriter writer, IXmlPersistenceContext persistenceContext)
        {
            base.SaveContent(writer, persistenceContext);

            // If
            if(If != null)
            {
                writer.WriteStartElement("If", XmlNamespace);
                XmlPersist.SaveObject(writer, If, persistenceContext);
                writer.WriteEndElement();
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="itemNode"></param>
        /// <param name="persistenceContext"></param>
        protected override void LoadContent(System.Xml.XPath.XPathNavigator itemNode, IXmlPersistenceContext persistenceContext)
        {
            base.LoadContent(itemNode, persistenceContext);

            // If
            XPathNavigator ifNode = itemNode.SelectSingleNode("al:If", persistenceContext.NamespaceManager);
            if (ifNode != null)
            {
                ifNode.MoveToFirstChild();
                If = XmlPersist.LoadObject<IExecutionCondition>(ifNode, persistenceContext);
            }
        }
    }
}
